package com.wonderful.compose.anim

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults.buttonColors
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.wonderful.compose.ui.theme.ComposeLearnTheme

/**
 * Describe: 动画
 * https://mp.weixin.qq.com/s?__biz=MzA5MzI3NjE2MA==&mid=2650290029&idx=1&sn=a57ab56fa49ee098fa0fe8623494c91c&chksm=886cc602bf1b4f144cec05f41d1988cb03e926b94e7cd0f8af3c77d371ce4ea96fbddfe3934e&scene=178&cur_album_id=1455589563531214850&search_click_id=#rd
 *
 * @author Wonderful
 * @time 2025/9/15 14:51
 */
class AnimActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeLearnTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    AnimContent()
                }
            }
        }
    }
}

@Preview
@Composable
fun AnimContent() {

    Column(modifier = Modifier.padding(20.dp)) {
        AnimatedVisibilityDemo()
        AnimateContentSizeDemo()
        AnimatedContentDemo()
        AnimationProgressBar()
        SwitchButtonColor()
        AnimationProgressBarWithTween()
        ExpandableText()
    }
}

@Composable
fun AnimatedVisibilityDemo(modifier: Modifier = Modifier) {
    var isExpand by remember { mutableStateOf(false) }
    FloatingActionButton(
        onClick = {
            isExpand = !isExpand
        },
        modifier = modifier
    ) {
        Row(
            modifier = Modifier.padding(horizontal = 16.dp)
        ) {
            Icon(
                imageVector = Icons.Default.Edit,
                contentDescription = null
            )
            AnimatedVisibility(isExpand) {
                Text(
                    text = "EDIT",
                    modifier = Modifier
                        .padding(start = 8.dp, top = 3.dp)
                )
            }
        }
    }
}

@Composable
fun AnimateContentSizeDemo(modifier: Modifier = Modifier) {
    var isExpand by remember { mutableStateOf(false) }
    Text(
        text = "text\ntext\ntext\ntext\ntext\ntext", modifier = modifier
            .padding(5.dp)
            .background(Color.Cyan)
            .animateContentSize()
            .clickable {
                isExpand = !isExpand
            },
        maxLines = if (isExpand) 10 else 2,
        overflow = TextOverflow.Ellipsis
    )
}

@Composable
fun AnimatedContentDemo(modifier: Modifier = Modifier) {
    DynamicTabContent()
}

@OptIn(ExperimentalAnimationApi::class)
@Composable
fun DynamicTabContent(
    modifier: Modifier = Modifier
        .fillMaxWidth()
        .height(100.dp)
) {
    var tab by remember { mutableIntStateOf(0) }
    Button(onClick = { tab = (tab + 1) % 3 }, modifier = modifier) {
        Text(text = "Next Tab")
    }
    AnimatedContent(targetState = tab) { tab ->
        when (tab) {
            0 -> TabView(tabName = "Tab 0", modifier)
            1 -> TabView(tabName = "Tab 1", modifier)
            2 -> TabView(tabName = "Tab 2", modifier)
        }
    }
}

@Composable
fun TabView(tabName: String, modifier: Modifier = Modifier) {
    Text(
        text = tabName,
        fontSize = 36.sp,
        modifier = modifier
            .fillMaxSize()
            .wrapContentSize(Alignment.Center)
            .background(color = Color.Green)
    )
}

/**
 * animateAsState: 一组函数的统称。目前Compose中支持以下animateAsState类型的函数
 * animateColorAsState
 * animateDpAsState
 * animateFloatAsState
 * animateIntAsState
 * animateLongAsState
 * animateSizeAsState
 * animateValueAsState
 * ...
 */

@Composable
fun AnimationProgressBar(modifier: Modifier = Modifier) {
    var progress by remember { mutableFloatStateOf(0f) }
    val animationProgress by animateFloatAsState(targetValue = progress, label = "progress")
    Column(modifier = modifier) {
        Button(onClick = { progress += 0.2f }) {
            Text(text = "Next Progress")
        }
        LinearProgressIndicator(progress = animationProgress)
    }
}

@Composable
fun SwitchButtonColor(modifier: Modifier = Modifier) {
    var flag by remember { mutableStateOf(false) }
    val animationColor by animateColorAsState(
        targetValue = if (flag) Color.Red else Color.Blue,
        label = "button"
    )
    Button(
        colors = buttonColors(containerColor = animationColor),
        onClick = { flag = !flag },
        modifier = modifier.size(150.dp, 60.dp)
    ) {
        Text(text = "Switch Color")
    }
}

/**
 * AnimationSpec
 * 这个参数可以定制这些动画函数的默认行为，将一些预设的动画效果调整成我们想要的样子
 * 比如说，如果想要调整动画的持续时间、动画的加速模式等等，都可以通过AnimationSpec实现。
 * Compose 提供了多种预设的AnimationSpec类型，最常用的有tween和spring
 * 在Compose当中，
 * tween函数可以用于指定动画的时长、延迟、加速模式这几个属性。
 *
 * spring函数是弹簧的意思，它是用于实现回弹动画效果的。
 * spring函数支持传入dampingRatio和stiffness这两个参数，
 * 其中 dampingRatio用于设置弹簧的弹性，stiffness用于设置弹簧的硬度。
 * DampingRatioNoBouncy 没有回弹效果
 * DampingRatioLowBouncy 低回弹效果
 * DampingRatioMediumBouncy 中等回弹效果
 * DampingRatioHighBouncy 高回弹效果
 * StiffnessLow 低硬度
 * StiffnessMediumLow 中等硬度
 * StiffnessMedium 中等硬度
 * StiffnessHigh 高硬度
 */

@Composable
fun AnimationProgressBarWithTween(modifier: Modifier = Modifier) {
    var progress by remember { mutableFloatStateOf(0f) }
    // tween函数默认会使用FastOutSlowInEasing，也就是先快后慢的动画加速模式
    // FastOutSlowInEasing
    // LinearOutSlowInEasing
    // FastOutLinearInEasing
    // LinearEasing
    val animationProgress by animateFloatAsState(
        targetValue = progress,
        label = "progress",
        animationSpec = tween(durationMillis = 2000)
    )
    Column(modifier = modifier) {
        Button(onClick = { progress += 0.2f }) {
            Text(text = "Next Progress")
        }
        LinearProgressIndicator(progress = animationProgress)
    }
}

@Composable
fun ExpandableText(modifier: Modifier = Modifier) {
    var isExpand by remember { mutableStateOf(false) }
    Text(
        text = "text\ntext\ntext\ntext\ntext\ntext", modifier = modifier
            .padding(5.dp)
            .background(Color.Cyan)
            .animateContentSize(
                animationSpec = spring(
                    dampingRatio = Spring.DampingRatioMediumBouncy,
                    stiffness = Spring.StiffnessMediumLow
                )
            )
            .clickable {
                isExpand = !isExpand
            },
        maxLines = if (isExpand) 10 else 2,
        overflow = TextOverflow.Ellipsis
    )
}